package net.woggle.shackbrowse;

import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.Timestamp;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.prefs.Preferences;
import java.util.regex.Pattern;

import net.woggle.shackbrowse.NetworkNotificationServers.OnGCMInteractListener;
import net.woggle.shackbrowse.ThreadListFragment.Filtword;

import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.actionbarsherlock.view.MenuItem;
import com.google.android.gms.gcm.GoogleCloudMessaging;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.app.backup.BackupManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.support.v4.app.NavUtils;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.text.InputType;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class PreferenceView extends SherlockPreferenceActivity
{
	private SharedPreferences _prefs;
	
	protected ProgressDialog _progressDialog;
	private NetworkNotificationServers _GCMAccess;

	private CheckBoxPreference _fastNotification;

	private CheckBoxPreference _slowNotification;

	
	@Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        doOrientation(-1);
        
        _prefs = PreferenceManager.getDefaultSharedPreferences(this);
        
        addPreferencesFromResource(R.xml.preferences);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        
        String versionName = "Unknown";
        try {
			versionName = this.getApplication().getPackageManager().getPackageInfo(getApplication().getPackageName(), 0 ).versionName;
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
        Preference customPref = (Preference) findPreference("versionName");
        customPref.setTitle("Version " + versionName);
        final Context cont = this;
        customPref.setOnPreferenceClickListener(new OnPreferenceClickListener(){

			@Override
			public boolean onPreferenceClick(Preference preference) {
				ChangeLog cl = new ChangeLog(cont);
		        cl.getFullLogDialog().show();
				return false;
			}}
        );
        
        Preference testNote = (Preference) findPreference("pref_testnote");
        testNote.setOnPreferenceClickListener(new OnPreferenceClickListener(){

			@Override
			public boolean onPreferenceClick(Preference preference) {
				SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(PreferenceView.this);
				
				NotificationCompat.Builder mBuilder =
				        new NotificationCompat.Builder(PreferenceView.this)
				        .setSmallIcon(R.drawable.icon)
				        .setContentTitle("Test")
				.setContentText("Only a test")
				.setTicker("Test Notification")
				.setAutoCancel(true);
				
				NotificationManager mNotificationManager =
					    (NotificationManager)PreferenceView.this.getSystemService(Context.NOTIFICATION_SERVICE);
				
				PendingIntent notifyPIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), 0);     
				mBuilder.setContentIntent(notifyPIntent);
				
				Notification notification = mBuilder.build();
				notification.sound = Uri.parse(prefs.getString("notificationSound", "DEFAULT_SOUND"));
				
				if (prefs.getBoolean("notificationVibrate", true))
					notification.defaults|= Notification.DEFAULT_VIBRATE;
				
				notification.flags |= Notification.FLAG_AUTO_CANCEL;
				notification.flags |= Notification.FLAG_SHOW_LIGHTS;
				
				notification.ledARGB = prefs.getInt("notificationColor", Color.GREEN);
				notification.ledOffMS = 1600;
				notification.ledOnMS = 100;
				// mId allows you to update the notification later on.
				int mId = 58401;
				mNotificationManager.notify(mId, notification);
				
				return false;
			}}
        );
        
        
        
        Preference donatePref = (Preference) findPreference("pref_donate");
        donatePref.setOnPreferenceClickListener(new OnPreferenceClickListener(){

			@Override
			public boolean onPreferenceClick(Preference preference) {
				// hey, thats the same thing I just wrote!
                Intent i = new Intent(cont, DonateActivity.class);
                startActivity(i);
				return false;
			}}
        );
        
        Preference clearcollapsed = (Preference) findPreference("pref_clearcollapsed");
        clearcollapsed.setOnPreferenceClickListener(new OnPreferenceClickListener(){

			@Override
			public boolean onPreferenceClick(Preference preference) {
				FileOutputStream _output = null;
				try
		        {
					_output = openFileOutput(ThreadListFragment.SUPERCOLLAPSED_CACHE_FILENAME, Activity.MODE_PRIVATE);
		            DataOutputStream out = new DataOutputStream(_output);
		            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
		            
		            // clear file
		            writer.write("");
		            writer.flush();
		            _output.close();
		            
		            _output = openFileOutput(ThreadListFragment.COLLAPSED_CACHE_FILENAME, Activity.MODE_PRIVATE);
		            out = new DataOutputStream(_output);
		            writer = new BufferedWriter(new OutputStreamWriter(out));
		            
		            // clear file
		            writer.write("");
		            writer.flush();
		            _output.close();
		        }
		        catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					AlertDialog.Builder builder = new AlertDialog.Builder(PreferenceView.this);
			        builder.setTitle("Error Clearing Collapsed");
			        builder.setMessage("Clear Failure");
			        builder.setNegativeButton("Ok", null);
			        builder.create().show();
				}
				finally
				{
					AlertDialog.Builder builder = new AlertDialog.Builder(PreferenceView.this);
			        builder.setTitle("Cleared Collapsed");
			        builder.setMessage("Successfully cleared. \nYou must refresh threads to see any change.");
			        builder.setNegativeButton("Ok", null);
			        builder.create().show();
				}
				return false;
			}}
        );
        
        Preference orientLock = (Preference)findPreference("orientLock");
        orientLock.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {

			@Override
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				doOrientation(Integer.parseInt((String)newValue));
				return true;
			}
					
		});   	
        
        Preference fontZoom = (Preference)findPreference("fontZoom");
        fontZoom.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
			@Override
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				AlertDialog.Builder builder = new AlertDialog.Builder(PreferenceView.this);
		        builder.setTitle("Font Size Change");
		        builder.setMessage("Changing the font size requires an app restart.");
		        builder.setPositiveButton("Restart Now", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int id) {
		            	setResult(PreferenceView.RESTART_APP);
				        finish();
		            }
		        });
		        builder.setNegativeButton("Deal with Bugs", null);
		        builder.create().show();
				return true;
			}
					
		});   	
        
        Preference favpane = (Preference)findPreference("showFavorites");
        favpane.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
			@Override
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				AlertDialog.Builder builder = new AlertDialog.Builder(PreferenceView.this);
		        builder.setTitle("App Change");
		        builder.setMessage("Changing Favorites pane visibility requires an app restart.");
		        builder.setPositiveButton("Restart Now", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int id) {
		            	setResult(PreferenceView.RESTART_APP);
				        finish();
		            }
		        });
		        builder.setNegativeButton("Deal with Bugs", null);
		        builder.create().show();
				return true;
			}
					
		});
        
        
        _slowNotification = (CheckBoxPreference)findPreference("slowNotification");
        _fastNotification = (CheckBoxPreference)findPreference("fastNotification");
        boolean PNenabled = _prefs.getBoolean("enableDonatorFeatures", false);
        _fastNotification.setEnabled(PNenabled);
        final OnGCMInteractListener GCMlistener = new OnGCMInteractListener(){
			@Override
			public void networkResult(String res) {
				Editor edit = _prefs.edit();
				if (res.contains("FAST REG"))
				{
					edit.putBoolean("slowNotification", false);
					edit.putBoolean("fastNotification", true);
					_fastNotification.setChecked(true);
					_slowNotification.setChecked(false);
					System.out.println("PUSHREG: SET FAST REG");
				}
				if (res.contains("SLOW REG"))
				{
					edit.putBoolean("slowNotification", true);
					edit.putBoolean("fastNotification", false);
					_fastNotification.setChecked(false);
					_slowNotification.setChecked(true);
					System.out.println("PUSHREG: SET SLOW REG");
				}
				if (res.contains("UNREG"))
				{
					edit.putBoolean("slowNotification", false);
					edit.putBoolean("fastNotification", false);
					_fastNotification.setChecked(false);
					_slowNotification.setChecked(false);
					System.out.println("PUSHREG: SET UNREG");
				}
				edit.commit();
				_progressDialog.dismiss();
			}};
        
        OnPreferenceChangeListener notificationOnPrefListener = new Preference.OnPreferenceChangeListener() {
			@Override
			public boolean onPreferenceChange(final Preference preference, Object newValue) {
		        if(newValue instanceof Boolean){
		            final Boolean checked = (Boolean)newValue;
		            
	                    boolean verified = _prefs.getBoolean("usernameVerified", false);
	    		        if (!verified)
	    		        {
	    		        	LoginForm login = new LoginForm(PreferenceView.this);
	    		        	login.setOnVerifiedListener(new LoginForm.OnVerifiedListener() {
	    						
								@Override
	    						public void onSuccess() {
	    							_progressDialog = new ProgressDialog(PreferenceView.this).show(PreferenceView.this, "Changing Notification Status", "Communicating with Shack Browse server...", true, true);
	    							
	    							_GCMAccess = new NetworkNotificationServers(PreferenceView.this, GCMlistener);
	    							if ((checked) && (preference.getKey().equalsIgnoreCase("fastNotification")))
	    								_GCMAccess.doRegisterTask("fastreg");
	    							else if ((checked) && (preference.getKey().equalsIgnoreCase("slowNotification")))
	    								_GCMAccess.doRegisterTask("slowreg");
	    							else
	    								_GCMAccess.doRegisterTask("unreg");
	    						}

	    						@Override
	    						public void onFailure() {
	    							_fastNotification.setChecked(false);
	    						}
	    					});
	    		        }
	    		        else
	    		        {
	    		        	_progressDialog = new ProgressDialog(PreferenceView.this).show(PreferenceView.this, "Changing Notification Status", "Communicating with Shack Browse server...", true, true);
							
							_GCMAccess = new NetworkNotificationServers(PreferenceView.this, GCMlistener);
							if ((checked) && (preference.getKey().equalsIgnoreCase("fastNotification")))
								_GCMAccess.doRegisterTask("fastreg");
							else if ((checked) && (preference.getKey().equalsIgnoreCase("slowNotification")))
								_GCMAccess.doRegisterTask("slowreg");
							else
								_GCMAccess.doRegisterTask("unreg");
	    		        }
		        }
		        return false;
		    }
					
		};
        
        _fastNotification.setOnPreferenceChangeListener(notificationOnPrefListener);
        _slowNotification.setOnPreferenceChangeListener(notificationOnPrefListener);
        
        
        final Preference apiUrl = (Preference)findPreference("apiUrl");
        apiUrl.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
			@Override
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				int i = 0;
				try 
				{
					i = Integer.parseInt((String) newValue);
				}
				catch (NumberFormatException e)
				{}
				
				if (i == 2)
				{
					AlertDialog.Builder builder = new AlertDialog.Builder(PreferenceView.this);
			        builder.setTitle("Custom API");
			        final View view = getLayoutInflater().inflate(R.layout.dialog_customapi, null);
			        final EditText input = (EditText) view.findViewById(R.id.apitext);
			        input.setText(_prefs.getString("apiCustom", ""));
			        builder.setView(view);
			        builder.setPositiveButton("Set API", new DialogInterface.OnClickListener() {
			            public void onClick(DialogInterface dialog, int id) {
			            	SharedPreferences.Editor editor = _prefs.edit();
			            	editor.putString("apiCustom", input.getText().toString());
			            	editor.commit();
			            }
			        });
			        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			            @SuppressLint("NewApi")
						public void onClick(DialogInterface dialog, int id) {
			            	
			            	SharedPreferences.Editor editor = apiUrl.getEditor();
			            	editor.putString("apiUrl", "0");
			            	editor.commit();
			            	if (android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.HONEYCOMB) {
			            		recreate();
			            	}
			            }
			        });
			        AlertDialog d = builder.create();
			        d.show();
				}
				return true;
			}
					
		});
        
        Preference pingPref = (Preference) findPreference("pref_ping");
        pingPref.setOnPreferenceClickListener(new OnPreferenceClickListener(){

			@Override
			public boolean onPreferenceClick(Preference preference) {
		    	new PingTask().execute();
				return false;
			}}
        );
        
        // first launch, try to set everything up
    	Intent i = getIntent();
    	Bundle args = i.getExtras();
		if (args != null && args.containsKey("pscreenkey"))
		{
			
			// the preference screen your item is in must be known
			PreferenceScreen pscreen = (PreferenceScreen) findPreference((String)args.get("pscreenkey"));
			this.setPreferenceScreen(pscreen);
		}
		
    }
	
	final static int RESTART_APP = 38;
    public void doOrientation (int _orientLock) 
    {
    	if (_orientLock == -1)
    	{
	    	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
	        _orientLock = Integer.parseInt(prefs.getString("orientLock", "0"));
    	}
        
        if (_orientLock == 0)
        	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
        if (_orientLock == 1)
        	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        if (_orientLock == 2)
        	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        if (_orientLock == 3)
        	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
        if (_orientLock == 4)
        	setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
    }

	@Override
	protected void onPause()
	{	
		BackupManager backup = new BackupManager(this);
		backup.dataChanged();
		super.onPause();
	}
	
	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                Intent upIntent = new Intent(this, MainActivity.class);
                if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
                    // This activity is not part of the application's task, so create a new task
                    // with a synthesized back stack.
                    TaskStackBuilder.from(this)
                            .addNextIntent(upIntent)
                            .startActivities();
                    finish();
                } else {
                    // This activity is part of the application's task, so simply
                    // navigate up to the hierarchical parent activity.
                    finish();
                }
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
	
    class PingTask extends AsyncTask<Void, Void, String>
	{
	    Exception _exception;
		private String _taskMode;
		
        @Override
        protected String doInBackground(Void... params)
        {
            try
            {
            	runOnUiThread(new Runnable(){
            		@Override public void run()
            		{
            			_progressDialog = ProgressDialog.show(PreferenceView.this, "Pinging", "Communicating with servers...");
            		}
            	});
            	
            	// warm up the servers
            	ShackApi.getPosts(3000000, PreferenceView.this, ShackApi.BASE_URL);
            	ShackApi.getPosts(3000000, PreferenceView.this, ShackApi.BASE_URL_ALT);
            	ShackApi.getPosts(3000000, PreferenceView.this, ShackApi.BASE_URL_ALT2);
            	
            	Long current = TimeDisplay.now();
            	ShackApi.getPosts(3000000, PreferenceView.this, ShackApi.BASE_URL);
            	float hughes = (TimeDisplay.now() - current);
            	
            	current = TimeDisplay.now();
            	ShackApi.getPosts(3000000, PreferenceView.this, ShackApi.BASE_URL_ALT);
            	float woggle = (TimeDisplay.now() - current);
            	
            	current = TimeDisplay.now();
            	ShackApi.getPosts(3000000, PreferenceView.this, ShackApi.BASE_URL_ALT2);
            	float appspot = (TimeDisplay.now() - current);
            	
                return hughes + " " + woggle + " " + appspot;
                
            }
            catch (Exception e)
            {
                Log.e("shackbrowse", "Error pinging", e);
                _exception = e;
                return null;
            }
        }
        
        @Override
        protected void onPostExecute(final String result)
        {
        	try {
        		Handler handler = new Handler();
        		handler.postDelayed(new Runnable() {
        		    public void run() {
        		    	_progressDialog.dismiss();
        		    	
        		    	AlertDialog.Builder builder = new AlertDialog.Builder(PreferenceView.this);
        		    	builder.setTitle("API Ping");
        		    	// Set up the input
        		    	String[] pingbits = result.split(Pattern.quote(" "));
        				builder.setMessage("arhughes: " + pingbits[0] + "\n" + "woggle: " + pingbits[1] + "\n" +"appspot: " + pingbits[2] + "\n");
        				builder.setNegativeButton("Close", null);
        		    	AlertDialog alert = builder.create();
        		        alert.setCanceledOnTouchOutside(false);
        		        alert.show();
        		        
        		    }}, 500);  // 700 milliseconds
        	}
        	catch (Exception e)
        	{
        		
        	}
            
            if (_exception != null)
            {
                ErrorDialog.display(PreferenceView.this, "Error", "Error pinging:\n" + _exception.getMessage());
            }
            else if (result == null)
            {
            	System.out.println("pushreg: err");
                ErrorDialog.display(PreferenceView.this, "Error", "Unknown ping error.");
            }
        }
	}
    
}
